package net.wicp.tams.common.test;

import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 对称加解密工具类
 * 
 * @author kahn
 */
public class AesCryptoUtil {

	private static Logger LOGGER = LoggerFactory.getLogger(AesCryptoUtil.class);

	// Cipher负责完成加密或解密工作
	private static Cipher cipher;
	static final String CIPHER_ALGORITHM_CBC = "AES/CBC/PKCS5Padding";

	static {
		// 生成Cipher对象,指定其支持的AES/CBC/PKCS7Padding算法
		try {
			// Security.addProvider(new BouncyCastleProvider());
			cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC);
		} catch (NoSuchAlgorithmException e) {
			LOGGER.error("No Such Algorithm", e);
		} catch (NoSuchPaddingException e) {
			LOGGER.error("No Such Padding", e);
		}
	}

	/**
	 * 加密
	 * 
	 * @param data
	 *            待加密数据
	 * @param key
	 *            密钥
	 * @return [0]iv [1]密文
	 */
	public static String[] encrypt(String data, String key) {
		String[] result = new String[2];
		Key sKeySpec = null;
		try {
			sKeySpec = new SecretKeySpec(Base64.decodeBase64(key.getBytes("UTF-8")), "AES");
			// 根据密钥，对Cipher对象进行初始化，ENCRYPT_MODE表示加密模式
			cipher.init(Cipher.ENCRYPT_MODE, sKeySpec);
			result[0] = Base64.encodeBase64String(cipher.getIV());
			result[1] = Base64.encodeBase64String(cipher.doFinal(data.getBytes("UTF-8")));
		} catch (IllegalBlockSizeException e) {
			LOGGER.error("IllegalBlockSize", e);
		} catch (BadPaddingException e) {
			LOGGER.error("BadPadding", e);
		} catch (UnsupportedEncodingException e) {
			LOGGER.error("UnsupportedEncoding", e);
		} catch (InvalidKeyException e) {
			LOGGER.error("InvalidKey", e);
		}
		return result;
	}

	/**
	 * 解密
	 * 
	 * @param data
	 *            待解密数据
	 * @param key
	 *            密钥
	 * @param iv
	 *            向量
	 * @return 明文
	 */
	public static String decrypt(String data, String key, String iv) {
		String result = "";
		Key sKeySpec = null;
		try {
			sKeySpec = new SecretKeySpec(Base64.decodeBase64(key.getBytes("UTF-8")), "AES");
			// 根据密钥，对Cipher对象进行初始化，DECRYPT_MODE表示加密模式
			cipher.init(Cipher.DECRYPT_MODE, sKeySpec, new IvParameterSpec(Base64.decodeBase64(iv.getBytes("UTF-8"))));
			result = new String(cipher.doFinal(Base64.decodeBase64(data.getBytes("UTF-8"))));
		} catch (InvalidKeyException e) {
			LOGGER.error("InvalidKey", e);
		} catch (InvalidAlgorithmParameterException e) {
			LOGGER.error("InvalidAlgorithmParameter", e);
		} catch (IllegalBlockSizeException e) {
			LOGGER.error("IllegalBlockSize", e);
		} catch (BadPaddingException e) {
			LOGGER.error("BadPadding", e);
		} catch (UnsupportedEncodingException e) {
			LOGGER.error("UnsupportedEncoding", e);
		}
		return result;
	}

}